"""
认证模块 - 数据模型
"""
from typing import Any, Dict, List

from pydantic import BaseModel, Field


class Principal(BaseModel):
    """
    认证主体，代表一个经过认证的用户或系统实体。
    这是在整个系统中传递身份信息的核心对象。
    """
    user_id: str = Field(..., description="用户的唯一标识符", alias="sub")
    username: str = Field(..., description="用户名")
    roles: List[str] = Field(default_factory=list, description="用户拥有的角色代码列表")
    permissions: List[str] = Field(default_factory=list, description="用户拥有的权限代码列表")
    enabled: bool = Field(True, description="账户是否启用")
    account_non_expired: bool = Field(True, description="账户是否未过期")
    account_non_locked: bool = Field(True, description="账户是否未锁定")
    credentials_non_expired: bool = Field(True, description="凭证是否未过期")
    extra_data: Dict[str, Any] = Field(default_factory=dict, description="额外的载荷数据")


class Token(BaseModel):
    """标准的 OAuth 2.0 令牌响应模型"""
    access_token: str = Field(..., description="访问令牌")
    refresh_token: str = Field(..., description="刷新令牌")
    token_type: str = Field(default="bearer", description="令牌类型")
    expires_in: int = Field(..., description="访问令牌的有效时间（秒）")


class TokenData(BaseModel):
    """令牌中存储的自定义数据模型 (payload)"""
    username: str | None = None


class ClientVerifyRequest(BaseModel):
    """用于内部客户端验证服务的数据模型"""
    client_id: str = Field(..., description="客户端ID")
    client_secret: str = Field(..., description="客户端密钥")
    grant_type: str | None = Field(default=None, description="授权类型")
    redirect_uri: str | None = Field(default=None, description="重定向URI")
    response_type: str | None = Field(default=None, description="响应类型")
    scope: str | None = Field(default=None, description="请求的范围")


class TokenIssueRequestDTO(BaseModel):
    """
    用于令牌颁发端点的请求体模型。
    兼容多种授权类型 (grant_type)，如 'password', 'client_credentials', 'refresh_token' 等。
    """
    grant_type: str = Field(..., description="授权类型 (e.g., 'password', 'client_credentials', 'refresh_token')")
    client_id: str = Field(..., description="客户端ID")
    client_secret: str | None = Field(default=None, description="客户端密钥 (在 'password', 'authorization_code' 模式下需要)")
    username: str | None = Field(default=None, description="用户名 (当 grant_type 为 'password' 时必需)")
    password: str | None = Field(default=None, description="密码 (当 grant_type 为 'password' 时必需)")
    scope: str | None = Field(default=None, description="请求的权限范围 (逗号或空格分隔)")
    redirect_uri: str | None = Field(default=None, description="重定向URI (用于 'authorization_code' 流程)")
    response_type: str | None = Field(default=None, description="响应类型 (用于 'authorization_code' 或 'implicit' 流程)")
    code: str | None = Field(default=None, description="授权码 (当 grant_type 为 'authorization_code' 时必需)")
    refresh_token: str | None = Field(default=None, description="刷新令牌 (当 grant_type 为 'refresh_token' 时必需)")


class TokenRevokeRequest(BaseModel):
    """
    用于令牌撤销端点的请求体模型 (RFC 7009)。
    """
    token: str = Field(..., description="要吊销的访问令牌或刷新令牌")
    token_type_hint: str | None = Field(default=None, description="可选的令牌类型提示 (e.g., 'access_token', 'refresh_token')")
